package base
{
	import com.dusk.util.ClassUtil;
	import com.dusk.util.StringUtil;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.getQualifiedClassName;
	
	public class BaseVO
	{
		// 字典用于缓存类描述信息
		public static var ClassDescribes:Dictionary = new Dictionary();
		
		// 当前对象的描述信息
		protected var classDescription:Object;
		
		// 当前类的类名
		private var _className:String;
		
		public function BaseVO()
		{
			super();
			_className = getQualifiedClassName(this);
			if(ClassDescribes[_className])
			{
				classDescription = ClassDescribes[_className];
			}
			else
			{
				classDescription = ClassUtil.describeClass(this);
				ClassDescribes[_className] = classDescription;
			}
		}
		
		// 从对象更新字段
		public function updateFromObject(data:Object) : void
		{
			if(!data) return;
			for(var key:String in data)
			{
				if(classDescription.hasOwnProperty(key))
				{
					buildField(key, data[key]);
				}
			}
		}
		
		// 从对象构建字段
		public function buildFromObject(data:Object) : void
		{
			if(!data) return;
			for(var key:String in data)
			{
				if(classDescription.hasOwnProperty(key))
				{
					buildField(key, data[key]);
				}
			}
		}
		
		// 从 XML 属性构建字段
		public function buildFromXMLAttr(xml:XML) : void
		{
			for(var key:String in classDescription)
			{
				try
				{
					this[key] = xml[key];
				}
				catch(err:Error)
				{
				}
			}
		}
		
		// 从 XML 构建字段
		public function buildFromXML(xml:XML) : void
		{
			var valueString:String = null;
			for(var key:String in classDescription)
			{
				valueString = xml[key].text();
				buildField(key, valueString);
			}
		}
		
		/**
		 * 构建字段
		 * @param fieldName 字段名
		 * @param fieldValue 字段值
		 * @example
		 * String 		"test"
		 * int 			111 or "111"
		 * Number 		111.1 or "111.1"
		 * Boolean 		true or "true"
		 * Vector 		pass
		 * Point 		"x,y" or [x,y]
		 * Rectangle 	"x,y,width,height" or [x,y,width,height]
		 * Vector3D 	"x,y,z" or [x,y,z]
		 */
		protected function buildField(fieldName:String, fieldValue:*) : void
		{
			var valueArray:Array = null;
			var vectorTypeRegExp:RegExp = null;
			var vectorTypeMatch:Array = null;
			var isPrimitiveVector:Boolean = false;
			var index:int = 0;
			var pointValue:Point = null;
			
			if(fieldValue == null)
			{
				return;
			}
			
			if(typeof fieldValue == "string")
			{
				valueArray = fieldValue.split(";");
				if(StringUtil.isWhitespace(fieldValue))
				{
					valueArray = null;
				}
			}
			else if(fieldValue is Array)
			{
				valueArray = fieldValue;
			}
			else
			{
				valueArray = fieldValue.toString().split(",");
			}
			
			switch(classDescription[fieldName])
			{
				case "Array":
					this[fieldName] = fieldValue == "" ? null : valueArray;
					break;
				case "int":
					this[fieldName] = int(fieldValue);
					break;
				case "Boolean":
					this[fieldName] = (fieldValue == "true" || int(fieldValue) > 0);
					break;
				case "flash.utils::Dictionary":
					// 处理字典类型（未提供具体实现）
					break;
				default:
					if(String(classDescription[fieldName]).indexOf("__AS3__.vec::Vector.<") != -1)
					{
						vectorTypeRegExp = /<(.*)>/;
						vectorTypeMatch = vectorTypeRegExp.exec(String(classDescription[fieldName]));
						isPrimitiveVector = false;
						
						switch(vectorTypeMatch[1])
						{
							case "int":
								this[fieldName] = new Vector.<int>();
								isPrimitiveVector = true;
								break;
							case "uint":
								this[fieldName] = new Vector.<uint>();
								isPrimitiveVector = true;
								break;
							case "String":
								this[fieldName] = new Vector.<String>();
								isPrimitiveVector = true;
								break;
							case "Number":
								this[fieldName] = new Vector.<Number>();
								isPrimitiveVector = true;
								break;
							case "flash.geom::Point":
								this[fieldName] = new Vector.<Point>();
								index = 0;
								while(index < valueArray.length)
								{
									pointValue = new Point(valueArray[index], valueArray[index + 1]);
									this[fieldName].push(pointValue);
									index += 2;
								}
								break;
						}
						
						if(isPrimitiveVector)
						{
							for each(var value:* in valueArray)
							{
								this[fieldName].push(value);
							}
						}
					}
					else
					{
						switch(classDescription[fieldName])
						{
							case "flash.geom::Point":
								if(valueArray)
								{
									this[fieldName] = new Point(valueArray[0], valueArray[1]);
								}
								break;
							case "flash.geom::Rectangle":
								if(valueArray)
								{
									this[fieldName] = new Rectangle(Number(valueArray[0]), Number(valueArray[1]), Number(valueArray[2]), Number(valueArray[3]));
								}
								break;
							case "flash.geom::Vector3D":
								if(valueArray.length > 0 && fieldValue != "")
								{
									var vector3DValue:Vector3D = new Vector3D();
									vector3DValue.x = valueArray[0];
									vector3DValue.y = valueArray[1];
									vector3DValue.z = valueArray[2];
									this[fieldName] = vector3DValue;
								}
								break;
							case "Object":
								var byteArray:ByteArray = new ByteArray();
								byteArray.writeObject(fieldValue);
								byteArray.position = 0;
								this[fieldName] = byteArray.readObject();
								byteArray.clear();
								break;
							default:
								try
								{
									this[fieldName] = fieldValue;
								}
								catch(err:Error)
								{
									this[fieldName] = null;
								}
								break;
						}
					}
					break;
			}
		}
		
		// 从 CSV 数据构建字段
		public function buildFromCSV(headers:Array, data:Array) : void
		{
			for(var i:int = 0; i < headers.length; i++)
			{
				buildField(headers[i], data[i]);
			}
		}
		
		// 克隆对象
		public function cloneToObject() : Object
		{
			var clonedObject:Object = {};
			for(var key:String in classDescription)
			{
				clonedObject[key] = this[key];
			}
			return clonedObject;
		}
		
		// 转换为字符串
		public function toString() : String
		{
			var str:String = "{";
			for(var key:String in classDescription)
			{
				str += "|" + key + ":" + this[key];
			}
			return str + "}";
		}
	}
}
